package modele;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.transaction.UserTransaction;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.safety.Whitelist;


@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class FacadeArticle {
	
	
    @PersistenceContext
    private EntityManager em;
    @Resource private UserTransaction ut;
    
    public String getResume(Article article){
    	
    	Document doc = null;
		StringTokenizer st = new StringTokenizer(article.getTexte());
		String resume = "";
		
		int k = 0;
		while (k < Config.nbMotsResume && st.hasMoreTokens()) {
			resume += " " + st.nextToken();
			k++;
		}

		resume += " ...";
		
		// Netoie le code html du resume
		doc = Jsoup.parse(resume);
		resume = doc.outerHtml();
		Whitelist w = Whitelist.basicWithImages()
		.addAttributes("img", "style", "width", "height");
		resume = Jsoup.clean(resume, w);
		
		return resume;
    }
    
    public boolean supprimerArticle(Membre auteurArticle, long idArticle){
    		
    		Article article = em.find(Article.class, idArticle);
			
   	
	    	if(article != null && article.getAuteur().getId() == auteurArticle.getId()){
	    		
	    		try {
	    			ut.begin();
	    			
	    			
	    			em.remove(em.merge(article));
	    			
	    			ut.commit();
	    			
	    			return true;
	    			
	    		} catch (Exception e) {
	    			e.printStackTrace();
	    			try {
	    				ut.rollback();
	    			}
	    			catch (Exception e1) {
	    				e1.printStackTrace();
	    			}
	    			
	    			return false;
	    		}
	    	}
	    	else{
	    		return false;
	    	}
    }
    
    public boolean commenterArticle(Membre auteurCom, Long idArticle, String texte){
    	boolean resultat = false;
    	
    	if( !auteurCom.isDroit_commenter()){
    		return resultat;
    	}
    	
    	Article article = null;
    	article = em.find(Article.class, idArticle);
    	
    	if (article!=null && auteurCom!=null){	
       	
        		try {
        			ut.begin();
                	Commentaire com = new Commentaire();
                	com.setArticle(article);
                	Date date=new Date();
                	com.setDate(date);
                	com.setAuteur(auteurCom);
                	com.setTexte(texte);
                	auteurCom.getCommentaires().add(com);
                	article.ajouterCommentaire(com);        
                	article.getAuteur().augmenterPoints(Config.nbPointsReceptionCom);
                	auteurCom.augmenterPoints(Config.nbPointsAjoutCom);
                	
                	if(auteurCom.getId()!=article.getAuteur().getId()){
                	Notification n = new Notification();
                	n.setAction(Config.notificationCommentaire);
                	n.setAuteurNotification(auteurCom);
                	n.setDate(date);
                	n.setReceveurNotification(article.getAuteur());
                	n.setArticle(article);
                	article.getAuteur().ajouterNotification(n);
                	em.persist(n);
                	}
                	
        			em.persist(com);
        			em.merge(article);
        			em.merge(auteurCom);
        			em.merge(article.getAuteur());
        			
        			ut.commit();
        		} catch (Exception e) {
        			try {
        				ut.rollback();
        			} 
        			catch (Exception e1) {
        				e1.printStackTrace();
        			}
        		}
        		resultat = true;
    		}
    	return resultat;
    	}
    
    public boolean noterArticle(Membre auteurNote, Long idArticle, int note){
    	
    	boolean resultat = false;
		
    	Article article = null;
    	article = em.find(Article.class, idArticle);
    	
    	for(NoteArticle n : article.getNotes()){
    		if(n.getMembre().getId()==idArticle){
    			return resultat;
    		}
    	}
    	
    	if(note<0 || note>5){
    		return resultat;
    	}
    	
		if (article!=null&&auteurNote!=null){

    		try {
    			ut.begin();
    			NoteArticle n =new NoteArticle();
    			n.setArticle(article);
    			n.setMembre(auteurNote);
    			n.setNote(note);
    			article.ajouterNote(n);
    			article.getAuteur().augmenterPoints(note);
    			auteurNote.augmenterPoints(Config.nbPointsAjoutNote);
    			
            	Notification noti = new Notification();
            	noti.setAction(Config.notificationNote);
            	noti.setAuteurNotification(auteurNote);
            	noti.setDate(new Date());
            	noti.setReceveurNotification(article.getAuteur());
            	noti.setArticle(article);
            	
            	article.getAuteur().ajouterNotification(noti);
    			
    			em.persist(noti);
    			em.merge(article);
    			em.merge(auteurNote);
    			em.merge(article.getAuteur());
    			ut.commit();
    		} catch (Exception e) {
    			try {
    				ut.rollback();
    			} 
    			catch (Exception e1) {
    				e1.printStackTrace();
    			}
    		}
    		resultat = true;
		}
		return resultat;
		
		
    }
    
    public boolean approuverCommentaire(Membre auteurApp, Long idCommentaire){
    	boolean resultat = false;
    	
    	Commentaire commentaire = null;
    	commentaire = em.find(Commentaire.class,idCommentaire);
    	
    	if (commentaire!=null&&auteurApp!=null){
    	
    	for(ApprobationCommentaire n : commentaire.getApprobations()){
    		if(n.getMembre().getId()==auteurApp.getId()){
    			return resultat;
    		}
    	}
    	
    	if(commentaire.getAuteur().getId()==auteurApp.getId()){
    		return resultat;
    	}
    	
    		try {
    			ut.begin();
    			ApprobationCommentaire app = new ApprobationCommentaire();
    			app.setCommentaire(commentaire);
    			app.setMembre(auteurApp);
    			
    			commentaire.getApprobations().add(app);
    			auteurApp.getApprobationscommentaires().add(app);
    			auteurApp.augmenterPoints(Config.nbPointAjoutApprobation);
    			commentaire.getAuteur().augmenterPoints(Config.nbPointReceptionApprobation);
    			
            	Notification noti = new Notification();
            	noti.setAction(Config.notificationApprobationCommentaire);
            	noti.setAuteurNotification(auteurApp);
            	noti.setDate(new Date());
            	noti.setReceveurNotification(commentaire.getAuteur());
            	noti.setCommentaire(commentaire);
            	
            	commentaire.getAuteur().ajouterNotification(noti);
    			
            	em.persist(noti);
    			em.persist(app);
    			em.merge(commentaire);
    			em.merge(auteurApp);
    			em.merge(commentaire.getAuteur());
    			ut.commit();
    		} catch (Exception e) {
    			try {
    				ut.rollback();
    			} 
    			catch (Exception e1) {
    				e1.printStackTrace();
    			}
    		}
    		resultat = true;
		}
		return resultat;
    	
    	
    }
   
    public boolean redigerArticle(Membre m, Long idSport, Long idCompetition, String texte, String titre){
    	
    	boolean resultat = false;

    	Competition competitionArticle = null;
    	Sport sportArticle = null; 
    	
    	if(!m.isDroit_rediger()){
    		return resultat;
    	}
    	
    	sportArticle = em.find(Sport.class, idSport);
		
		if (idCompetition != null){ // L'article est rataché a une competition en particulier
			competitionArticle = em.find(Competition.class, idCompetition);
		}
		
		if (m != null && sportArticle != null){
			try {
    			ut.begin();
    			Article art = new Article();
    			art.setAuteur(m);
    			art.setSport(sportArticle);
    			art.setTitre(titre);
    			art.setTexte(texte);
    			art.setCompetition(competitionArticle);
            	art.setDate(new Date());
            	m.getArticles().add(art);
            	m.augmenterPoints(Config.nbPointsAjoutCom);
            	sportArticle.getArticles().add(art);
            	
            	em.persist(art);
        		
            	if(competitionArticle != null){
	            	competitionArticle.getArticles().add(art);
	            	em.merge(competitionArticle);
            	}
    			
            	em.merge(m);
    			em.merge(sportArticle);
    			
    			ut.commit();
    		} catch (Exception e) {
    			try {
    				ut.rollback();
    			} 
    			catch (Exception e1) {
    				e1.printStackTrace();
    			}
    		}
    		resultat = true;
		}
		
      	return resultat;
	}
    
    public boolean ajouterCompetition(Membre auteur, Long idSport, String nom){
    	
    	boolean resultat = false;
    	
    	if(!auteur.isDroit_admin()){
    		return false;
    	}
    	
    	Sport sport = null;
    	sport = em.find(Sport.class,idSport);
		
		if (auteur!=null&&sport!=null){
    		try {
    			ut.begin();
    			Competition comp = new Competition();
    			      	    
    			comp.setName(nom);
    			comp.setSport(sport);
    			//comp.getAdministrateurs().add(auteur.get(0));
    			//auteur.setCompetitions_admin(comp);
    			em.persist(comp);
    	      	sport.getCompetitions().add(comp);
    			em.merge(sport);
    			ut.commit();
    		} catch (Exception e) {
    			try {
    				ut.rollback();
    			} 
    			catch (Exception e1) {
    				e1.printStackTrace();
    			}
    		}
    		resultat = true;
			
		}
		return resultat;
     }
    
    
    public Article majArticle(Long idArticle){
    	Article res = null;
    	res = em.find(Article.class, idArticle);
    	return res;
    	
    }
    
    public ArrayList<Commentaire> getDerniersCommentairesTriesDate(int i){
    	
		CriteriaBuilder builder = em.getCriteriaBuilder();
		CriteriaQuery<Commentaire> criteria = builder.createQuery( Commentaire.class );
		Root<Commentaire> menuRoot = criteria.from( Commentaire.class );
		criteria.select(menuRoot);
		ArrayList<Commentaire> resultat = (ArrayList<Commentaire>) em.createQuery(criteria).getResultList();
		
		Collections.sort(resultat,new ComparatorCommentaireDate());
		
		
		if (resultat.size()<i){
			return resultat;
		}
		else{
			ArrayList<Commentaire> res =  new ArrayList<Commentaire>();
			for (int j=0;j<5;j++){
				res.add(resultat.get(j));
			}
			return res;
		}
    	
    }
    
	public List<Commentaire> getCommentairesTriesDate(Long idArticle){
		
		Article art = em.find(Article.class, idArticle);
		if (art==null){
			return null;
		}
		else{
			List<Commentaire> liste = (List<Commentaire>) art.getCommentaires();
			Collections.sort(liste,new ComparatorCommentaireDate());
			return liste;
		}
	}
	
	public Competition getCompetition(Long idCompetition){
		Competition comp = em.find(Competition.class, idCompetition);
		return comp;
		
	}
		
	public Sport getSport(Long idSport){
		Sport s = em.find(Sport.class, idSport);
		return s;
		
	}	
  
    
    
    
}
    
    

